#include "GRO_Gui.h"
#include "GRO_Group.h"

namespace GRO
{
    
    
// Returns true if the string was (probably) changed
bool textInputEvent(SDL_Event& event, string& buffer, Uint16& pos, Uint16 max)
{
    if(event.type == SDL_KEYDOWN)
    {
        // Insert
        if(event.key.keysym.sym == SDLK_LEFT)
        {
            if(pos > 0)
                pos--;
        }
        else if(event.key.keysym.sym == SDLK_RIGHT)
        {
            if(pos < max)
                pos++;
        }
        else if(event.key.keysym.sym == SDLK_RETURN)
        {
            if(int(buffer.size()) >= max - 1) // strlen ignores \0
                return 0;
            string::iterator e = buffer.begin();
            int i = 0;
            while(i < pos && e != buffer.end())
            {
                ++e; ++i;
            }
            buffer.insert(e, '\n');
            pos++;
            return 1;
        }
        else if(event.key.keysym.sym != SDLK_BACKSPACE)
        {
            if(int(buffer.size()) >= max - 1) // strlen ignores \0
                return 0;
            char c = (char)event.key.keysym.unicode;  // Use unicode to abstract keyboard configs
            if(31 < c && c < 127)
            {
                string::iterator e = buffer.begin();
                int i = 0;
                while(i < pos && e != buffer.end())
                {
                    ++e; ++i;
                }
                buffer.insert(e, c);
                pos++;
                return 1;
            }
        }
        else // backspace
        {
            if(buffer.size() == 0 || pos == 0)
                return 0;
            string::iterator e = buffer.begin();
            int i = 0;
            while(i < pos - 1 && e != buffer.end())
            {
                ++e; ++i;
            }
            buffer.erase(e);
            pos--;
            return 1;
        }
    }
    return 0;
}





EventResult PointerCursor::event(const SDL_Event& event)
{
    InputButtonSettings* button = NULL;
    bool setScroll = false;
    //Uint16 scrollBlockSize = 1;
    
    switch(event.type)
    {
        case SDL_MOUSEMOTION:
            if(mouse == NULL)
                return EventResult();
            mx = mouse->x = event.button.x;
            my = mouse->y = event.button.y;
            dx = mouse->dx = event.motion.xrel;
            dy = mouse->dy = event.motion.yrel;
            mouse->left = event.motion.state & SDL_BUTTON_LEFT;
            mouse->middle = event.motion.state & SDL_BUTTON_MIDDLE;
            mouse->right = event.motion.state & SDL_BUTTON_RIGHT;
            
            if(leftClick.currentWidget != NULL)
            {
                if(leftClick.drag == NULL)
                {
                    if(leftClick.pressed && leftClick.drag == NULL)
                    {
                        leftClick.currentWidget->action(this, ACTION_DRAG);
                        //leftClick.drag = leftClick.currentWidget->drag(mx, my);
                    }
                    else if(leftClick.useMotion)
                    {
                        leftClick.currentWidget->action(this, ACTION_DRAG);
                    }
                }
            }
            if(middleClick.currentWidget != NULL)
            {
                if(middleClick.drag == NULL)
                {
                    if(middleClick.pressed && middleClick.drag == NULL)
                    {
                        middleClick.currentWidget->action(this, ACTION_DRAG);
                        //middleClick.drag = middleClick.currentWidget->drag(mx, my);
                    }
                    else if(middleClick.useMotion)
                    {
                        middleClick.currentWidget->action(this, ACTION_DRAG);
                    }
                }
            }
            if(rightClick.currentWidget != NULL)
            {
                if(rightClick.drag == NULL)
                {
                    if(rightClick.pressed)
                    {
                        rightClick.currentWidget->action(this, ACTION_DRAG);
                        //rightClick.drag = rightClick.currentWidget->drag(mx, my);
                    }
                    else if(rightClick.useMotion)
                    {
                        rightClick.currentWidget->action(this, ACTION_DRAG);
                    }
                }
            }
            
            
            return EventResult(buttonFocus, true);
        case SDL_MOUSEBUTTONDOWN:
            if(mouse == NULL)
                return EventResult();
            mx = mouse->x = event.button.x;
            my = mouse->y = event.button.y;
            
            if(event.button.button == SDL_BUTTON_WHEELDOWN)
            {
                // Call widget scroll function (if wheel action is set to that)
                // Should I check with InRect here first?  Then the widget's scroll function
                // can be used by both Cursors (x,y) and Navigators (no x,y).
                if(scrollFocus != NULL)
                {
                    if(scrollFocus->scroll(DOWN, 1) == NULL)  // I prefer up/down scrolling first, before I try horizontal
                        scrollFocus->scroll(RIGHT, 1);
                }
                return EventResult(scrollFocus, true);
            }
            else if(event.button.button == SDL_BUTTON_WHEELUP)
            {
                // Call widget scroll function (if wheel action is set to that)
                if(scrollFocus != NULL)
                {
                    if(scrollFocus->scroll(UP, 1) == NULL)  // I prefer up/down scrolling first, before I try horizontal
                        scrollFocus->scroll(LEFT, 1);
                }
                return EventResult(scrollFocus, true);
            }
            else if(event.button.button == SDL_BUTTON_LEFT)
            {
                mouse->left = true;
                button = &leftClick;
                setScroll = (scrollSelectMode == SCROLL_LEFT_CLICK);
            }
            else if(event.button.button == SDL_BUTTON_MIDDLE)
            {
                mouse->middle = true;
                button = &middleClick;
                setScroll = (scrollSelectMode == SCROLL_MIDDLE_CLICK);
            }
            else if(event.button.button == SDL_BUTTON_RIGHT)
            {
                mouse->right = true;
                button = &rightClick;
                setScroll = (scrollSelectMode == SCROLL_RIGHT_CLICK);
            }
            
            if(button != NULL)
            {
                if(gui == NULL)
                    return EventResult(NULL, true);
                
                button->currentWidget = gui->findWidget(mx, my, true, true);
                
                
                if(setScroll || (scrollSelectMode == SCROLL_BUTTON_FOCUS && button->downAction == ACTION_PRESS))
                {
                    scrollFocus = button->currentWidget;
                    while(scrollFocus != NULL && !scrollFocus->grabScrollFocus)
                    {
                        scrollFocus = scrollFocus->getGroup();
                    }
                }
                
                if(button->currentWidget != NULL)
                {
                    button->currentWidget->action(this, button->downAction);
                }
                return EventResult(button->currentWidget, true);
            }
            return EventResult(NULL, true);
        case SDL_MOUSEBUTTONUP:
            if(mouse == NULL)
                return EventResult();
            mx = mouse->x = event.button.x;
            my = mouse->y = event.button.y;
            
            if(event.button.button == SDL_BUTTON_LEFT)
            {
                mouse->left = false;
                button = &leftClick;
            }
            else if(event.button.button == SDL_BUTTON_MIDDLE)
            {
                mouse->middle = false;
                button = &middleClick;
            }
            else if(event.button.button == SDL_BUTTON_RIGHT)
            {
                mouse->right = false;
                button = &rightClick;
            }
            
            if(button != NULL)
            {
                if(gui == NULL)
                    return EventResult(NULL, true);
                
                button->pressed = false;
                if(button->drag != NULL)
                {
                    // Find the widget that you're over, and drop the item onto it.
                    button->currentWidget = gui->findWidget(mx, my, true, true);
                    if(button->currentWidget != NULL)
                    {
                        
                        
                        
                        button->currentWidget = NULL;  // reset the current widget so I don't cause another action.
                    }
                    else
                    {
                        // If there's no widget/group there, just send it back to the original group (if it's a widget)
                        if(button->drag->hasWidget())
                        {
                            Group* g = button->drag->widget->getGroup();
                            if(g != NULL)
                                ;//g->drop(button->drag, mx, my);
                        }
                    }
                }
                else if(button->currentWidget != NULL)
                {
                    button->currentWidget->action(this, button->upAction);
                    button->currentWidget = NULL;
                }
                
                return EventResult(button->currentWidget, true);
            }
            return EventResult(NULL, true);
        case SDL_JOYAXISMOTION:
            return axisEvent(event);
        case SDL_JOYHATMOTION:
            return hatEvent(event);
        case SDL_JOYBALLMOTION:
            return ballEvent(event);
        case SDL_JOYBUTTONDOWN:
            if(joystick == NULL || joystick->joystick == NULL || event.jbutton.which != joystick->index)
                return EventResult();
            if(joystick->leftClick != NULL && event.jbutton.button == joystick->leftClick->button)
            {
                joystick->leftClick->currentWidget = gui->findWidget(mx, my, joystick->leftClick->panelFocus, joystick->leftClick->panelGrabbable);
                if(joystick->leftClick->currentWidget != NULL)
                    joystick->leftClick->currentWidget->action(this, joystick->leftClick->downAction);
                return EventResult(joystick->leftClick->currentWidget, true);
            }
            if(joystick->middleClick != NULL && event.jbutton.button == joystick->middleClick->button)
            {
                joystick->middleClick->currentWidget = gui->findWidget(mx, my, joystick->middleClick->panelFocus, joystick->middleClick->panelGrabbable);
                if(joystick->middleClick->currentWidget != NULL)
                    joystick->middleClick->currentWidget->action(this, joystick->middleClick->downAction);
                return EventResult(joystick->middleClick->currentWidget, true);
            }
            if(joystick->rightClick != NULL && event.jbutton.button == joystick->rightClick->button)
            {
                joystick->rightClick->currentWidget = gui->findWidget(mx, my, joystick->rightClick->panelFocus, joystick->rightClick->panelGrabbable);
                if(joystick->rightClick->currentWidget != NULL)
                    joystick->rightClick->currentWidget->action(this, joystick->rightClick->downAction);
                return EventResult(joystick->rightClick->currentWidget, true);
            }
            // ... Other buttons
            return EventResult();
        case SDL_JOYBUTTONUP:
            if(joystick == NULL || joystick->joystick == NULL || event.jbutton.which != joystick->index)
                return EventResult();
            if(joystick->leftClick != NULL && event.jbutton.button == joystick->leftClick->button)
            {
                if(joystick->leftClick->currentWidget != NULL)
                {
                    joystick->leftClick->currentWidget->action(this, joystick->leftClick->upAction);
                    joystick->leftClick->currentWidget = NULL;
                }
                return EventResult(joystick->leftClick->currentWidget, true);
            }
            if(joystick->middleClick != NULL && event.jbutton.button == joystick->middleClick->button)
            {
                if(joystick->middleClick->currentWidget != NULL)
                {
                    joystick->middleClick->currentWidget->action(this, joystick->middleClick->upAction);
                    joystick->middleClick->currentWidget = NULL;
                }
                return EventResult(joystick->middleClick->currentWidget, true);
            }
            if(joystick->rightClick != NULL && event.jbutton.button == joystick->rightClick->button)
            {
                if(joystick->rightClick->currentWidget != NULL)
                {
                    joystick->rightClick->currentWidget->action(this, joystick->rightClick->upAction);
                    joystick->rightClick->currentWidget = NULL;
                }
                return EventResult(joystick->rightClick->currentWidget, true);
            }
            // ... Other buttons
            
            return EventResult();
            //return buttonEvent(event);
        case SDL_KEYDOWN:
            if(keyboard == NULL || keyboard->keyboard == NULL)
                return EventResult();
            keyboard->keyboard->key = event.key.keysym.sym;
            keyboard->keyboard->mod = event.key.keysym.mod;
            keyboard->keyboard->unicode = event.key.keysym.unicode;
            
            if(keyboard->up != NULL && event.key.keysym.sym == keyboard->up->button)
            {
                keyboard->movingUp = true;
                // If too many keys are down, cancel all keys
                if(keyboard->movingUp + keyboard->movingDown + keyboard->movingLeft + keyboard->movingRight >= 3)
                {
                    keyboard->movingUp = keyboard->movingDown = keyboard->movingLeft = keyboard->movingRight = false;
                }
                keyboard->movingDown = false;
                return EventResult(NULL, true);
            }
            if(keyboard->down != NULL && event.key.keysym.sym == keyboard->down->button)
            {
                keyboard->movingDown = true;
                // If too many keys are down, cancel all keys
                if(keyboard->movingUp + keyboard->movingDown + keyboard->movingLeft + keyboard->movingRight >= 3)
                {
                    keyboard->movingUp = keyboard->movingDown = keyboard->movingLeft = keyboard->movingRight = false;
                }
                keyboard->movingUp = false;
                return EventResult(NULL, true);
            }
            if(keyboard->left != NULL && event.key.keysym.sym == keyboard->left->button)
            {
                keyboard->movingLeft = true;
                // If too many keys are down, cancel all keys
                if(keyboard->movingUp + keyboard->movingDown + keyboard->movingLeft + keyboard->movingRight >= 3)
                {
                    keyboard->movingUp = keyboard->movingDown = keyboard->movingLeft = keyboard->movingRight = false;
                }
                keyboard->movingRight = false;
                return EventResult(NULL, true);
            }
            if(keyboard->right != NULL && event.key.keysym.sym == keyboard->right->button)
            {
                keyboard->movingRight = true;
                // If too many keys are down, cancel all keys
                if(keyboard->movingUp + keyboard->movingDown + keyboard->movingLeft + keyboard->movingRight >= 3)
                {
                    keyboard->movingUp = keyboard->movingDown = keyboard->movingLeft = keyboard->movingRight = false;
                }
                keyboard->movingLeft = false;
                return EventResult(NULL, true);
            }
            if(keyboard->leftClick != NULL && event.key.keysym.sym == keyboard->leftClick->button)
            {
                keyboard->leftClick->currentWidget = gui->findWidget(mx, my, keyboard->leftClick->panelFocus, keyboard->leftClick->panelGrabbable);
                if(keyboard->leftClick->currentWidget != NULL)
                    keyboard->leftClick->currentWidget->action(this, keyboard->leftClick->downAction);
                return EventResult(keyboard->leftClick->currentWidget, true);
            }
            if(keyboard->middleClick != NULL && event.key.keysym.sym == keyboard->middleClick->button)
            {
                keyboard->middleClick->currentWidget = gui->findWidget(mx, my, keyboard->middleClick->panelFocus, keyboard->middleClick->panelGrabbable);
                if(keyboard->middleClick->currentWidget != NULL)
                    keyboard->middleClick->currentWidget->action(this, keyboard->middleClick->downAction);
                return EventResult(keyboard->middleClick->currentWidget, true);
            }
            if(keyboard->rightClick != NULL && event.key.keysym.sym == keyboard->rightClick->button)
            {
                keyboard->rightClick->currentWidget = gui->findWidget(mx, my, keyboard->rightClick->panelFocus, keyboard->rightClick->panelGrabbable);
                if(keyboard->rightClick->currentWidget != NULL)
                    keyboard->rightClick->currentWidget->action(this, keyboard->rightClick->downAction);
                return EventResult(keyboard->rightClick->currentWidget, true);
            }
            // ... Other buttons
            return EventResult();
        case SDL_KEYUP:
            if(keyboard == NULL || keyboard->keyboard == NULL)
                return EventResult();
            keyboard->keyboard->key = event.key.keysym.sym;
            keyboard->keyboard->mod = event.key.keysym.mod;
            keyboard->keyboard->unicode = event.key.keysym.unicode;
            
            if(keyboard->up != NULL && event.key.keysym.sym == keyboard->up->button)
            {
                keyboard->movingUp = false;
                if(!keyboard->movingUp && !keyboard->movingDown && !keyboard->movingLeft && !keyboard->movingRight)
                    keyboard->vel = keyboard->initVel;
                return EventResult(NULL, true);
            }
            if(keyboard->down != NULL && event.key.keysym.sym == keyboard->down->button)
            {
                keyboard->movingDown = false;
                if(!keyboard->movingUp && !keyboard->movingDown && !keyboard->movingLeft && !keyboard->movingRight)
                    keyboard->vel = keyboard->initVel;
                return EventResult(NULL, true);
            }
            if(keyboard->left != NULL && event.key.keysym.sym == keyboard->left->button)
            {
                keyboard->movingLeft = false;
                if(!keyboard->movingUp && !keyboard->movingDown && !keyboard->movingLeft && !keyboard->movingRight)
                    keyboard->vel = keyboard->initVel;
                return EventResult(NULL, true);
            }
            if(keyboard->right != NULL && event.key.keysym.sym == keyboard->right->button)
            {
                keyboard->movingRight = false;
                if(!keyboard->movingUp && !keyboard->movingDown && !keyboard->movingLeft && !keyboard->movingRight)
                    keyboard->vel = keyboard->initVel;
                return EventResult(NULL, true);
            }
            if(keyboard->leftClick != NULL && event.key.keysym.sym == keyboard->leftClick->button)
            {
                if(keyboard->leftClick->currentWidget != NULL)
                {
                    keyboard->leftClick->currentWidget->action(this, keyboard->leftClick->upAction);
                    keyboard->leftClick->currentWidget = NULL;
                }
                return EventResult(keyboard->leftClick->currentWidget, true);
            }
            if(keyboard->middleClick != NULL && event.key.keysym.sym == keyboard->middleClick->button)
            {
                if(keyboard->middleClick->currentWidget != NULL)
                {
                    keyboard->middleClick->currentWidget->action(this, keyboard->middleClick->upAction);
                    keyboard->middleClick->currentWidget = NULL;
                }
                return EventResult(keyboard->middleClick->currentWidget, true);
            }
            if(keyboard->rightClick != NULL && event.key.keysym.sym == keyboard->rightClick->button)
            {
                if(keyboard->rightClick->currentWidget != NULL)
                {
                    keyboard->rightClick->currentWidget->action(this, keyboard->rightClick->upAction);
                    keyboard->rightClick->currentWidget = NULL;
                }
                return EventResult(keyboard->rightClick->currentWidget, true);
            }
            // ... Other buttons
            
            return EventResult();
        default:
            return EventResult();
    }
}

// Update stuff, hoverFocus for now.
void PointerCursor::update()
{
    // Keyboard/joystick cursor movement
    if(keyboard != NULL && gui != NULL)
    {
        dx = 0;
        dy = 0;
        if(keyboard->movingUp)
        {
            fmy -= keyboard->vel * gui->dt;
            dy = int(fmy) - my;
            my = int(fmy);
        }
        else if(keyboard->movingDown)
        {
            fmy += keyboard->vel * gui->dt;
            dy = int(fmy) - my;
            my = int(fmy);
        }
        if(keyboard->movingLeft)
        {
            fmx -= keyboard->vel * gui->dt;
            dx = int(fmx) - mx;
            mx = int(fmx);
        }
        else if(keyboard->movingRight)
        {
            fmx += keyboard->vel * gui->dt;
            dx = int(fmx) - mx;
            mx = int(fmx);
        }
        if(keyboard->movingUp || keyboard->movingDown || keyboard->movingLeft || keyboard->movingRight)
        {
            keyboard->vel += keyboard->accel * gui->dt;
            if(keyboard->vel > keyboard->velMax)
                keyboard->vel = keyboard->velMax;
        }
        if(dx != 0 || dy != 0)
        {
            if(keyboard->leftClick != NULL && keyboard->leftClick->currentWidget != NULL)
                keyboard->leftClick->currentWidget->onDrag.emit();
                //keyboard->leftClick->currentWidget->action(this, ACTION_DRAG);
            if(keyboard->middleClick != NULL && keyboard->middleClick->currentWidget != NULL)
                keyboard->middleClick->currentWidget->onDrag.emit();
                //keyboard->middleClick->currentWidget->action(this, ACTION_DRAG);
            if(keyboard->rightClick != NULL && keyboard->rightClick->currentWidget != NULL)
                keyboard->rightClick->currentWidget->onDrag.emit();
                //keyboard->rightClick->currentWidget->action(this, ACTION_DRAG);
            
            if(hoverFocus != NULL)
                hoverFocus->onMotion.emit();
        }
        if(mx < gui->pos.x)
        {
            fmx = mx = gui->pos.x;
        }
        //else if(gui->screen != NULL && mx >= gui->screen->w)
        else if(mx >= gui->pos.x + int(gui->dims.w))
        {
            fmx = mx = gui->pos.x + gui->dims.w - 1;
        }
        if(my < gui->pos.y)
        {
            fmy = my = gui->pos.y;
        }
        //else if(gui->screen != NULL && my >= gui->screen->h)
        else if(my >= gui->pos.y + int(gui->dims.h))
        {
            fmy = my = gui->pos.y + gui->dims.h - 1;
        }
    }
    else if(joystick != NULL && gui != NULL)
    {
        dx = 0;
        dy = 0;
        if(joystick->movingUp)
        {
            fmy -= joystick->vel * gui->dt;
            dy = int(fmy) - my;
            my = int(fmy);
        }
        else if(joystick->movingDown)
        {
            fmy += joystick->vel * gui->dt;
            dy = int(fmy) - my;
            my = int(fmy);
        }
        if(joystick->movingLeft)
        {
            fmx -= joystick->vel * gui->dt;
            dx = int(fmx) - mx;
            mx = int(fmx);
        }
        else if(joystick->movingRight)
        {
            fmx += joystick->vel * gui->dt;
            dx = int(fmx) - mx;
            mx = int(fmx);
        }
        if(joystick->movingUp || joystick->movingDown || joystick->movingLeft || joystick->movingRight)
        {
            joystick->vel += joystick->accel * gui->dt;
            if(joystick->vel > joystick->velMax)
                joystick->vel = joystick->velMax;
        }
        else
            joystick->vel = joystick->initVel;
        if(dx != 0 || dy != 0)
        {
            if(joystick->leftClick != NULL && joystick->leftClick->currentWidget != NULL)
                joystick->leftClick->currentWidget->onDrag.emit();
                //joystick->leftClick->currentWidget->action(this, ACTION_DRAG);
            if(joystick->middleClick != NULL && joystick->middleClick->currentWidget != NULL)
                joystick->middleClick->currentWidget->onDrag.emit();
                //joystick->middleClick->currentWidget->action(this, ACTION_DRAG);
            if(joystick->rightClick != NULL && joystick->rightClick->currentWidget != NULL)
                joystick->rightClick->currentWidget->onDrag.emit();
                //joystick->rightClick->currentWidget->action(this, ACTION_DRAG);
            
            if(hoverFocus != NULL)
                hoverFocus->onMotion.emit();
        }
        //if(mx < 0)
        if(mx < gui->pos.x)
        {
            fmx = mx = gui->pos.x;
        }
        //else if(gui->screen != NULL && mx >= gui->screen->w)
        else if(mx >= gui->pos.x + int(gui->dims.w))
        {
            fmx = mx = gui->pos.x + gui->dims.w - 1;
        }
        if(my < gui->pos.y)
        {
            fmy = my = gui->pos.y;
        }
        //else if(gui->screen != NULL && my >= gui->screen->h)
        else if(my >= gui->pos.y + int(gui->dims.h))
        {
            fmy = my = gui->pos.y + gui->dims.h - 1;
        }
    }
    
    // Enter/leave events and searching for the current hovered widget.
    if(updateHoverFocus && gui != NULL)
    {
        Widget* old = hoverFocus;
        hoverFocus = gui->findWidget(mx, my);
        if(hoverFocus != NULL)
        {
            if(old == NULL)
            {
                hoverFocus->onEnter.emit();
            }
            else if(hoverFocus != old)
            {
                old->onLeave.emit();
                hoverFocus->onEnter.emit();
            }
        }
    }
    // Hover event
    // I don't think it would be good to have this happen when updateHoverFocus is off...
    if(hoverFocus != NULL)
    {
        if(scrollSelectMode == SCROLL_HOVER_FOCUS)
        {
            scrollFocus = hoverFocus;
            while(scrollFocus != NULL && !scrollFocus->grabScrollFocus)
            {
                scrollFocus = scrollFocus->getGroup();
            }
        }
        
        hoverFocus->onHover.emit();
        if(!updateHoverFocus)
            hoverFocus = NULL;  // This will protect us from weird usage.
    }
}

void PointerCursor::draw()
{
    if(gui == NULL || image == NULL || gui->getRenderer() == NULL)
        return;
    if(image != NULL)
    {
        SDL_Rect d = {Sint16(mx), Sint16(my), 1, 1};
        gui->getRenderer()->Blit(image, NULL, &d);
    }
}



        void NavCursor::draw()
        {
            if(gui == NULL || gui->getRenderer() == NULL)
                return;
            /*if(image != NULL)
            {
                SDL_Rect d = {mx, my, 0, 0};
                currentRenderer->Blit(gui, image, NULL, &d);
            }*/
            if(currentWidget != NULL && (!currentWidget->isFolded() || alwaysDraw))
            {
                gui->getRenderer()->RectFilledBlend(currentWidget->pos.x, currentWidget->pos.y, currentWidget->pos.x + currentWidget->dims.w - 1, currentWidget->pos.y + currentWidget->dims.h - 1, 0xff0000, 100);
            }
        }


        
        EventResult NavCursor::event(const SDL_Event& event)
        {
            switch(event.type)
            {
                case SDL_JOYAXISMOTION:
                    return axisEvent(event);
                case SDL_JOYHATMOTION:
                    return hatEvent(event);
                case SDL_JOYBALLMOTION:
                    return ballEvent(event);
                case SDL_JOYBUTTONDOWN:
                case SDL_JOYBUTTONUP:
                    return buttonEvent(event);
                case SDL_KEYDOWN:
                    if(keyboard == NULL || keyboard->keyboard == NULL)
                        return EventResult();
                    keyboard->keyboard->key = event.key.keysym.sym;
                    keyboard->keyboard->mod = event.key.keysym.mod;
                    keyboard->keyboard->unicode = event.key.keysym.unicode;

                    if(keyboard->up != NULL && event.key.keysym.sym == keyboard->up->button)
                    {
                        currentWidget = movement(UP);
                        return EventResult(NULL, true);
                    }
                    if(keyboard->down != NULL && event.key.keysym.sym == keyboard->down->button)
                    {
                        currentWidget = movement(DOWN);
                        return EventResult(NULL, true);
                    }
                    if(keyboard->left != NULL && event.key.keysym.sym == keyboard->left->button)
                    {
                        currentWidget = movement(LEFT);
                        return EventResult(NULL, true);
                    }
                    if(keyboard->right != NULL && event.key.keysym.sym == keyboard->right->button)
                    {
                        currentWidget = movement(RIGHT);
                        return EventResult(NULL, true);
                    }
                    if(keyboard->leftClick != NULL && event.key.keysym.sym == keyboard->leftClick->button)
                    {
                        if(currentWidget != NULL)
                            currentWidget->action(this, keyboard->leftClick->downAction);
                        return EventResult(currentWidget, true);
                    }
                    if(keyboard->middleClick != NULL && event.key.keysym.sym == keyboard->middleClick->button)
                    {
                        if(currentWidget != NULL)
                            currentWidget->action(this, keyboard->middleClick->downAction);
                        return EventResult(currentWidget, true);
                    }
                    if(keyboard->rightClick != NULL && event.key.keysym.sym == keyboard->rightClick->button)
                    {
                        if(currentWidget != NULL)
                            currentWidget->action(this, keyboard->rightClick->downAction);
                        return EventResult(currentWidget, true);
                    }
                    // Call widget function
                    return EventResult(currentWidget, true);
                case SDL_KEYUP:
                    if(keyboard == NULL || keyboard->keyboard == NULL)
                        return EventResult();
                    keyboard->keyboard->key = event.key.keysym.sym;
                    keyboard->keyboard->mod = event.key.keysym.mod;
                    keyboard->keyboard->unicode = event.key.keysym.unicode;
                    
                    if(keyboard->leftClick != NULL && event.key.keysym.sym == keyboard->leftClick->button)
                    {
                        if(currentWidget != NULL)
                            currentWidget->action(this, keyboard->leftClick->upAction);
                        return EventResult(currentWidget, true);
                    }
                    if(keyboard->middleClick != NULL && event.key.keysym.sym == keyboard->middleClick->button)
                    {
                        if(currentWidget != NULL)
                            currentWidget->action(this, keyboard->middleClick->upAction);
                        return EventResult(currentWidget, true);
                    }
                    if(keyboard->rightClick != NULL && event.key.keysym.sym == keyboard->rightClick->button)
                    {
                        if(currentWidget != NULL)
                            currentWidget->action(this, keyboard->rightClick->upAction);
                        return EventResult(currentWidget, true);
                    }
                    return EventResult(currentWidget, true);
                default:
                    return EventResult();
            }
        }


        Widget* NavCursor::movement(DirectionEnum direction)
        {
            /*if(currentNode != NULL)
            {
                // Move to new node
                NavNode* old = currentNode;
                currentNode = currentNode->movement(direction);
                if(currentNode != NULL)
                {
                    // If the node changed, tell both about it
                    if(old != currentNode)
                    {
                        old->leave();
                        currentNode->enter();
                    }
                    return currentNode->widget;
                }
            }*/
            return NULL;
        }


}
